package framework.grid.data;


import framework.fault.IFaultTolerantPeer;
import framework.util.PeerEdge;
import framework.util.PeerNode;

import java.io.Serializable;
import java.rmi.RemoteException;
import java.util.HashSet;


public class ReplicatedNodeMetaData implements INodeMetaData, Serializable {

	private HashSet<IRemoteNodeMetaData> replicas;
	
	public static ReplicatedNodeMetaData createInstance(IFaultTolerantPeer[] peers) throws RemoteException {
		HashSet<IRemoteNodeMetaData> replicas = new HashSet<IRemoteNodeMetaData>();
		for (int i=0; i<peers.length; i++) {
			replicas.add(peers[i].createRemoteNodeMetaData());
		}
		return new ReplicatedNodeMetaData(replicas);
	}
	public static ReplicatedNodeMetaData copyInstance
		(ReplicatedNodeMetaData oldData, IFaultTolerantPeer[] peers) 
	throws RemoteException {
		HashSet<IRemoteNodeMetaData> replicas = new HashSet<IRemoteNodeMetaData>();
		for (int i=0; i<peers.length; i++) {
			IRemoteNodeMetaData replica = peers[i].createRemoteNodeMetaData();
			replica.setNode(oldData.getNode());
			replica.setRefs(oldData.getRefs());
			replicas.add(replica);
		}
		return new ReplicatedNodeMetaData(replicas);
	}
	
	private ReplicatedNodeMetaData(HashSet<IRemoteNodeMetaData> replicas) {
		this.replicas = replicas;
	}
	
	@Override
	public void setNode(PeerNode node) throws RemoteException {
		for (IRemoteNodeMetaData data: replicas) {
			try {
				data.setNode(node);
			} catch (RemoteException e) {
				//Some of the remote data's peer is offline
			}
		}
	}

	@Override
	public PeerNode getNode() throws RemoteException {
		for (IRemoteNodeMetaData data: replicas) {
			try {
				return data.getNode();
			} catch (RemoteException e) {
				//Some of the remote data's peer is offline
			}
		}		
		return null;
	}

	@Override
	public PeerEdge getRef(int level) throws RemoteException {
		for (IRemoteNodeMetaData data: replicas) {
			try {
				return data.getRef(level);
			} catch (RemoteException e) {
				//Some of the remote data's peer is offline
			}
		}
		return null;
	}

	@Override
	public void setRef(int level, PeerEdge edge) throws RemoteException {
		for (IRemoteNodeMetaData data: replicas) {
			try {
				data.setRef(level, edge);
			} catch (RemoteException e) {
				//Some of the remote data's peer is offline
			}
		}
	}
	@Override
	public PeerEdge[] getRefs() throws RemoteException {
		for (IRemoteNodeMetaData data: replicas) {
			try {
				return data.getRefs();
			} catch (RemoteException e) {
				//Some of the remote data's peer is offline
			}
		}
		return null;
	}
	@Override
	public void setRefs(PeerEdge[] edges) throws RemoteException {
		for (IRemoteNodeMetaData data: replicas) {
			try {
				data.setRefs(edges);
			} catch (RemoteException e) {
				//Some of the remote data's peer is offline
			}
		}
	}

}
